package com.xcc.java_base.zerocopy;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;

/**
 * 采用sendFile零拷贝
 */
public class MyNewClient {

    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 8888));
        socketChannel.configureBlocking(true);
        //定义文件路径
        String fileName = "E:\\学习\\springcloud.zip";
        FileChannel fileChannel = new FileInputStream(fileName).getChannel();

        long m8 = 8 * 1024 * 1024;
        long count = (long)Math.ceil(fileChannel.size() * 1.0 / m8 );


        long startTime = System.currentTimeMillis();
        long total = 0l;
        long startPosition = 0;
        long endPosition = 0;
        int size = 0;
        while (size < count) {
            size++;
            endPosition = Math.min(size * m8, fileChannel.size());
            //TODO 底层使用的就是sendFile，这里只发生了2次拷贝，2次上下文切换
            //拷贝：通过DMA将磁盘文件拷贝到内核中，然后就是从(socket)内核拷贝到网卡。不需要经过用户
            total += fileChannel.transferTo(startPosition,endPosition, socketChannel);
            startPosition = endPosition;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("发送总字节数： "+total+" , 耗时： "+(endTime-startTime)+"ms");
        fileChannel.close();
        socketChannel.close();
    }

}
